

/******************************************************************************

Copyright (C), 2001-2011, DCN Co., Ltd.

******************************************************************************
File Name	  : System1Action.c
Version 	  : Initial Draft
Author		  : Hust
Created 	  : 2023/1/14
Last Modified :
Description   : system function
Function List :
		  CheckFrameAct
		  CheckFrameValid_Act
		  CheckMiss_Act
		  CheckPackEnd_Act
		  CheckUpdate_Act
		  EraseMem_Act
		  GetCmd_Act
		  GetPackIndex_Act
		  GetPackSize_Act
		  isFrameInTableAct
		  isPackValid_Act
		  JumpApp_Act
		  ModuleInfo_Act
		  PROG_Act
		  PushErrorTable_Act
		  PushFrame_Act
		  RestoreBus
		  RetryReq_Act
		  SendRespAct
		  SetPara_Act
		  Silence_Act
		  Timer0_Act
		  Timer0_Act_stop
		  Timer1_Act
		  Timer1_Act_stop
		  UpdateCpltResp_Act
		  UpdateTerminal_Act
History 	  :
1.Date		  : 2023/1/14
Author		: Hust
Modification: Created file

******************************************************************************/

/*----------------------------------------------*
 * include headfile 							*
 *----------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "Board.h"

#include "System1Action.h"

/*----------------------------------------------*
 * variables typedef							 *
 *----------------------------------------------*/

/*----------------------------------------------*
 * macros										*
 *----------------------------------------------*/

/*----------------------------------------------*
 * constants									*
 *----------------------------------------------*/

/*----------------------------------------------*
 * external variables							*
 *----------------------------------------------*/

/*----------------------------------------------*
 * project-wide global variables				*
 *----------------------------------------------*/

/*----------------------------------------------*
 * module-wide global variables 				*
 *----------------------------------------------*/

/*----------------------------------------------*
 * external routine prototypes					*
 *----------------------------------------------*/

/*----------------------------------------------*
 * internal routine prototypes					*
 *----------------------------------------------*/
//extern __no_init  uint32_t mOtaFlag @ 0x20003000;
/*----------------------------------------------*
 * routines' implementations					*
 *----------------------------------------------*/
VS_VOID InitSys_Act (VS_VOID)
{
    memset(&gOta_info,0,sizeof(CAN_OTA_INFO_STRU));
	memcpy(&gModlInfo,(uint32_t*)USER_DATA_START_ADDRESS,sizeof(MODL_INFO_STRU));
	gModlInfo.dev_modl_id |= MODULE_SN;
	
}


VS_BOOL isDealMsg_Act(VS_VOID)
{
    DebugTrace("\r\n |isDealMsg_Act() entry--- ");
	
	if (gRxMsg.header.IDE == CAN_CMD_ID_TPYE)
	{
#if (									CAN_CMD_ID_TPYE==CAN_ID_STD)
		if ((gRxMsg.header.ExtId >= CAN_CMD_FRAME_ID) && (gRxMsg.header.ExtId <= CAN_PACK_FRAME_END_ID))
#else
		if ((gRxMsg.header.ExtId >= CAN_CMD_FRAME_ID) && (gRxMsg.header.ExtId <= CAN_PACK_FRAME_END_ID))
#endif

		{
			DebugTrace("\r\n |isDealMsg_Act() exit---: 1 ");
			return TRUE;
		}
		else 
		{
			DebugTrace("\r\n |isDealMsg_Act() exit---: 2 ");
			return FALSE;
		}
        }
	else
	{
	    DebugTrace("\r\n |isDealMsg_Act() exit---: 3 ");
	    return FALSE;
	}


    DebugTrace("\r\n |isDealMsg_Act() exit---: 4 ");
}


VS_BOOL isFrameValid_Act(VS_VOID) //VS_UINT8 CheckFrameValid_Act(VS_VOID)
{
	uint8_t rslt;
	static uint8_t pre_frame_index;
	uint8_t cur_frame_index;
	uint8_t rx_byte;
	uint32_t bin_size;

	cur_frame_index 	= gOta_info.cmd - BIN_frame_start;

	if (cur_frame_index == pre_frame_index + 1)
	{
		pre_frame_index 	= cur_frame_index;
		rslt				= TRUE;
	}
	else 
		rslt = FALSE;

	return rslt;
}




/*****************************************************************************
 Prototype	  : CheckPackBegin_Act
 Description  : check pack information at begin of pack transmition
				1: Is pack continuous
				2: Is retry time is 0
				3: Is pack index in the error table
				
 Input		  : VS_VOID  
 Output 	  : None
 Return Value :  push ok;push overflow;
 Calls		  : 
 Called By	  : 
 
  History		 :
  1.Date		 : 2023/1/15
	Author		 : Hust
	Modification : Created function

*****************************************************************************/
VS_UINT8 CheckPackBegin_Act(VS_VOID)
{
	PACK_INDEX_ST_ENUM rslt;
	int32_t tmp;

	if (gOta_info.pack_cur_index <= gOta_info.pack_pre_index)
		rslt = PK_IDX_INVALID;
	else 
	{
		tmp 				= gOta_info.pack_cur_index - gOta_info.pack_pre_index;

		if (tmp == 1) /* check contionus  */
		{
			rslt				= PK_IDX_CONTIONUS;
		}
		else if (tmp <= PACK_ERR_TABLE_SIZE - gOta_info.err_idx) /* error index is pushed into error table */
		{
			rslt				= PK_IDX_MISS;
		}
		else 
		{
			rslt				= PK_IDX_MISS_OVERFLOW;
		}

	}

	return rslt;
}


VS_VOID ReSetPack_Act(VS_VOID)
{
	gOta_info.pack_ptr	= & (gOta_info.pack[0]);
}


VS_BOOL isPackFinish_Act(VS_VOID)
{
	//	PACK_INDEX_ST_ENUM rslt;
	if (gOta_info.pack_rcved_cnt == gOta_info.pack_sent_cnt)
	{
		return TRUE;
	}
	else 
		return FALSE;

}


VS_BOOL isBinCplt_Act(VS_VOID)
{
	if ((gOta_info.bin_size == gOta_info.bin_sent_cnt)
		&& (gOta_info.bin_rcved_cnt == gOta_info.bin_sent_cnt))
		{
			/* BEGIN: Added by Hust, 2023/1/15 */
			/* check CRC */
			/* END:   Added by Hust, 2023/1/15	 PN: */
			return TRUE;
		}
	else 
		return FALSE;

}


VS_BOOL EraseMem_Act(VS_VOID)
{
	VS_BOOL 		rslt;
	uint32_t		end_addr = gOta_info.bin_flash_start_addr + gOta_info.bin_size - 1;

	if (gOta_info.bin_flash_start_addr % FLASH_PAGE_SIZE)
		rslt = FALSE;
	else 
	{
#if 0

		while (erase_addr <= end_addr)
		{
			if (FLASH_If_Erase(erase_addr) != 0)
			{
				rslt				= FALSE;
				break;
			}

			erase_addr			+= FLASH_PAGE_SIZE;
		}

#else

		if (FLASH_If_Erase_range(gOta_info.bin_flash_start_addr, end_addr) != 0)
		{
			rslt				= FALSE;
		}
		else
		{
			rslt				= TRUE;
		}

#endif
	}

	return rslt;

}


VS_UINT8 GetCmd_Act(VS_VOID)
{
	if (gRxMsg.header.ExtId == OTA_CMD_ID)
	{
		gOta_info.cmd		= gRxMsg.data[0];

		switch (gOta_info.cmd)
		{
			case OTA_START_cmd:
				gOta_info.ota_module_id =
					 (gRxMsg.data[4] << 24) | (gRxMsg.data[5] << 16) | (gRxMsg.data[6] << 8) | (gRxMsg.data[7]);
				gOta_info.ota_module_mask = (gRxMsg.data[1] << 16) | (gRxMsg.data[2] << 8) | (gRxMsg.data[3]);
				break;

			case OTA_VER_cmd:
				gOta_info.ota_sw_ver =
					 (gRxMsg.data[4] << 24) | (gRxMsg.data[5] << 16) | (gRxMsg.data[6] << 8) | (gRxMsg.data[7]);
				gOta_info.ota_hw_ver = (gRxMsg.data[1] << 16) | (gRxMsg.data[2] << 8) | (gRxMsg.data[3]);
				break;

			case OTA_ERASE_cmd:
				gOta_info.erase_addr =
					 (gRxMsg.data[4] << 24) | (gRxMsg.data[5] << 16) | (gRxMsg.data[6] << 8) | (gRxMsg.data[7]);
				gOta_info.erase_length = (gRxMsg.data[1] << 16) | (gRxMsg.data[2] << 8) | (gRxMsg.data[3]);
				break;

			case OTA_PARA_cmd:
				gOta_info.timeout1 = (gRxMsg.data[6] << 8) | (gRxMsg.data[7]);
				gOta_info.retry_time = (gRxMsg.data[4] << 8) | (gRxMsg.data[5]);
				break;

			case BIN_TRANS_START_cmd:
				gOta_info.bin_flash_start_addr =
					 (gRxMsg.data[4] << 24) | (gRxMsg.data[5] << 16) | (gRxMsg.data[6] << 8) | (gRxMsg.data[7]);
				gOta_info.bin_size = (gRxMsg.data[1] << 16) | (gRxMsg.data[2] << 8) | (gRxMsg.data[3]);
				break;

			case BIN_CPLT_cmd:
				gOta_info.bin_crc =
					 (gRxMsg.data[4] << 24) | (gRxMsg.data[5] << 16) | (gRxMsg.data[6] << 8) | (gRxMsg.data[7]);
				gOta_info.bin_sent_cnt = (gRxMsg.data[1] << 16) | (gRxMsg.data[2] << 8) | (gRxMsg.data[3]);
				break;

			default:
				break;
		}
	}

	return gOta_info.cmd;
}


VS_VOID JumpApp_Act(VS_VOID)
{
    DebugTrace("\r\n |JumpApp_Act() entry--- ");
	
	JumpToApplication(APPLICATION_ADDRESS);

    DebugTrace("\r\n |JumpApp_Act() exit---: 1 ");
}


VS_VOID PROG_Act(VS_VOID)
{
	FLASH_If_Write((uint32_t)gOta_info.bin_flash_ptr,(uint32_t*)(&(gOta_info.pack)),gOta_info.pack_size);
	gOta_info.bin_flash_ptr += gOta_info.pack_size; 
}


//#define PACK_NOT_IN_ERROR_TABLE 0xff
#define PACK_DEL_FROM_ERROR_TABLE 0xffffffff


VS_UINT8 CheckPackIndexInErrTab_Act(VS_VOID)
{
	uint8_t 		sch_idx = 0;
	uint8_t 		rslt = FALSE;

	if (gOta_info.err_idx == 0)
	{
		rslt				= PACK_NOT_IN_ERROR_TABLE;
	}
	else 
	{
		while (sch_idx > gOta_info.err_idx)
		{
			if (gOta_info.pack_err_table[sch_idx] == gOta_info.pack_cur_index)
			{
				rslt				= PACK_IN_ERROR_TABLE;
				break;
			}
		}
	}

	return rslt;

}


VS_UINT8 RmvPackIdxFromErrTab_Act(VS_UINT8 param1) //VS_BOOL RmvPackIdxFromErrTab_Act(VS_UINT32)
{
	uint8_t idx ;

	for (idx = 0; idx < gOta_info.err_idx; ++idx)
	{
		if (gOta_info.pack_err_table[gOta_info.err_idx] == param1)
		{
			gOta_info.pack_err_table[idx] = PACK_DEL_FROM_ERROR_TABLE;
			break;
		}
	}
	return idx;
}


#if 0


VS_UINT8 PushErrorPackTable_Act(VS_VOID)
{
	gOta_info.err_idx++;

	if (gOta_info.err_idx >= PACK_ERR_TABLE_SIZE)
	{
		gOta_info.err_idx	= 0;
		return FALSE;
	}
	else 
	{
		gOta_info.pack_pre_index++;
		gOta_info.pack_err_table[gOta_info.err_idx] = gOta_info.pack_pre_index;
		return TRUE;
	}
}


#endif


VS_UINT8 PushErrorPack2Tab_Act(VS_UINT8 st)
{
	PACK_INDEX_ST_ENUM rslt = PK_IDX_CONTIONUS;
	uint8_t 		offset;

	if (st)
	{
		offset				= 1;
	}
	else 
	{
		offset				= 0;
	}

	//	gOta_info.err_idx++;
	while (gOta_info.pack_pre_index < (gOta_info.pack_cur_index - offset))
	{

		if (gOta_info.err_idx >= PACK_ERR_TABLE_SIZE)
		{
			gOta_info.err_idx	= 0;
			rslt				= PK_IDX_MISS_OVERFLOW;
			break;
		}
		else 
		{
			gOta_info.pack_pre_index++;
			gOta_info.pack_err_table[gOta_info.err_idx] = gOta_info.pack_pre_index;
			gOta_info.err_idx++;
			rslt				= PK_IDX_MISS;
		}
	}

	return rslt;
}


VS_VOID PushFrame2Pack_Act(VS_VOID)
{
	memcpy(gOta_info.pack_ptr, & (gOta_info.buf), 8);
	gOta_info.pack_ptr	+= 8;
	gOta_info.pack_rcved_cnt += 8;
}



VS_VOID RestoreBus_Act(VS_VOID)
{
	gModlInfo.module_silence_st = MODULE_BUS_NORMAL_st;

}


VS_VOID RetryReq_Act(VS_VOID)
{
}


VS_VOID SendRespAct(VS_VOID)
{
}


VS_VOID SetPara_Act(VS_VOID)
{
}


VS_VOID Silence_Act(VS_VOID)
{
	gModlInfo.module_silence_st = MODULE_BUS_SILENCE_st;
}


VS_VOID Timer0_Act(SEM_EVENT_TYPE event, VS_UINT ticks)
{
	TIMER_ACT(gTimer0, ticks, event);
}


VS_VOID Timer0_Act_stop(VS_VOID)
{
	TIMER_STOP_ACT(gTimer0);
}


VS_VOID Timer1_Act(SEM_EVENT_TYPE event, VS_UINT ticks)
{
	TIMER_ACT(gTimer1, ticks, event);
}


VS_VOID Timer1_Act_stop(VS_VOID)
{
	TIMER_STOP_ACT(gTimer1);
}


VS_VOID UpdateCpltResp_Act(VS_VOID)
{
}


VS_VOID UpdateTerminal_Act(VS_VOID)
{
}






//extern VS_UINT8 GetCmd_Act (VS_VOID);
VS_BOOL CheckDevInfo_Act(VS_VOID)
{
	if ((gOta_info.ota_hw_ver == gModlInfo.dev_hw_ver) &&
		 	 (gOta_info.ota_hw_ver > gModlInfo.dev_sw_ver))
	{
		return TRUE;
	}
	else 
	{
		return FALSE;
	}
}


VS_VOID ModlRst_Act(VS_VOID)
{
    
	__set_FAULTMASK(1);
	NVIC_SystemReset();
}
VS_VOID ModleInfoResp_Act(VS_VOID)
{
    
}
VS_VOID OtaInit_Act(VS_VOID)
{
    
}


//extern VS_UINT8 RmvPackIdxFromErrTab_Act (VS_UINT8 param1);
VS_BOOL isAppValid_Act(VS_VOID)
{
	if (((* (__IO uint32_t *) APPLICATION_ADDRESS) & 0x2FFE0000) == 0x20000000)
		return TRUE;

	else 
		return FALSE;
    
}
VS_BOOL isOtaFlag_Act(VS_VOID)
{
    
	if (IS_UPDATE_APP_KEY ==  mOtaFlag )
		return FALSE;

	else 
		return TRUE;
}

VS_BOOL isOtaImplmt_Act(VS_VOID)
{
	if((gOta_info.bin_sent_cnt==gOta_info.bin_rcved_cnt)
		&&(gOta_info.bin_crc==gOta_info.bin_rcved_crc))
		return TRUE;
	else
		return FALSE;
}

VS_BOOL isOtaModuleId_Act(VS_VOID)
{
	if(gOta_info.ota_module_id == gModlInfo.dev_modl_id & gOta_info.ota_module_mask) 
		return TRUE;
	else
		return FALSE;
}

//extern VS_BOOL isPackFinish_Act (VS_VOID);
VS_UINT8 test_Act(VS_INT param1)
{
    MSG_DBG(CONSOLE_MSG, ("trace:%d\n",param1));
}


